package com.luobo.structure.decorator;

/**
 * 23种设计模式之:装饰模式
 * 当需要给一个现有类添加附加职责，而又不能采用生成子类的方法进行扩充时。例如，该类被隐藏或者该类是终极类或者采用继承方式会产生大量的子类。
 * 当需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时，采用继承关系很难实现，而采用装饰模式却很好实现。
 * 当对象的功能要求可以动态地添加，也可以再动态地撤销时。
 *
 * 抽象构件（Cake）角色：定义一个抽象接口以规范准备接收附加责任的对象。
 * 具体构件（Concrete Cake）角色：实现抽象构件，通过装饰角色为其添加一些职责。
 * 抽象装饰（Decorator）角色：继承抽象构件，并包含具体构件的实例，可以通过其子类扩展具体构件的功能。
 * 具体装饰（ConcreteDecorator）角色：实现抽象装饰的相关方法，并给具体构件对象添加附加的责任。
 *
 * 通常情况下，扩展一个类的功能会使用继承方式来实现。但继承具有静态特征，耦合度高，并且随着扩展功能的增多，子类会很膨胀。如果使用组合关系来创建一个包装对象（即装饰对象）来包裹真实对象，并在保持真实对象的类结构不变的前提下，为其提供额外的功能，这就是装饰模式的目标。下面来分析其基本结构和实现方法。
 */
public class DecoratorPattern {

    public static void main(String[] args) {

        //普通手抓饼
        Cake cake1 = new BaseCake();
        System.out.println(cake1.getCake() + ":" + cake1.getPrice() + "元");

        //手抓饼+鸡蛋
        cake1 = new AddEggCake(new BaseCake());
        System.out.println(cake1.getCake() + ":" + cake1.getPrice() + "元");

        //手抓饼+ 鸡蛋 + 根肠
        cake1 = new AddSusageCake(new AddEggCake(new BaseCake()));
        System.out.println(cake1.getCake() + ":" + cake1.getPrice() + "元");


        Cake cake = new AddEggCake(new AddSusageCake(new AddEggCake(new BaseCake())));

        System.out.println(cake.getCake()+":"+cake.getPrice()+ "元");

    }
}
